================ uCOS Port - Code ================ main.cpp ======== Allocate Stack -------------- .. code-block:: c // prototype for startup task void StartupTask(void* pdata); // allocate a stack for the startup task static OS_STK StartupStk[APP_TASK_START_STK_SIZE]; // allocate the print buffer PRINT_DEFINEBUFFER(); main() ====== .. code-block:: c int main(void) { INT8U err; scb2300_t SCBParams = { /* Initial SCB Parameters */ .PLL_M_Mul = 12, /* PLL Multiplier. Valid values 6 through 512*/ .PLL_N_Div = 1, /* PLL Divider. Valid values 1 through 32 */ .PLL_Fcco = 288000000, /* Frequency (Hz) of PLL output */ .CCLK_Div = 6, /* CPU Clock divider, cclk */ .MAMMode = MAMCR_PARTIAL, /* MAM mode Partial is the preferred setting for Rev -,A parts */ .MAMTim = MAMTIM_AUTOCFG, /* Let initMAM calculate the optimal MAM timing */ }; /* pre-initialize so we can use the serial port, etc.*/ initHardware(&SCBParams); RETAILMSG(1, ( "main: Built %s %s.\n\r\n\r", __DATE__, __TIME__)); // initialize the OS DEBUGMSG(1, ("main: Running OSInit()...\n\r")); OSInit(); // create the startup task DEBUGMSG(1, ("main: Creating start up task\n\r")); err = OSTaskCreate(StartupTask, (void*)0, (void*)&StartupStk[APP_TASK_START_STK_SIZE-1], APP_TASK_START_PRIO); if (err != OS_NO_ERR) { DEBUGMSG(1, ("main: failed creating start up task: %d\n\r", err)); while(TRUE); //park on error } DEBUGMSG(1, ("Starting SBC5206 Hardware setup...\n\r")); // start the OS OSStart(); // We never get here. RETAILMSG(1, ( "main: Programming Assignment #6: Exiting.\n\r\n\r")); return 0; } Tasks.c ======= .. code-block:: c #include "includes.h" // OS includes #include "print.h" #include "uarts.h" #include "init.h" // allocate the stacks for each task static OS_STK Task1Stk[APP_TASK_DEFAULT_STK_SIZE]; static OS_STK Task2Stk[APP_TASK_DEFAULT_STK_SIZE]; static OS_STK Task3Stk[APP_TASK_DEFAULT_STK_SIZE]; #define MP3BUFFERSIZE 256 //?????? INT8U buffer[MP3BUFFERSIZE]; // allocate queue and events OS_EVENT * MySem; OS_EVENT * MyQueue; void *Q1[Q1_SIZE]; // task prototypes void Task1(void* pdata); void Task2(void* pdata); void Task3(void* pdata); static void SetLED(BOOLEAN On); //get external refrence to the print buffer PRINT_BUFFER(); // // this task is the initial task running, started by main(). It begins the system tick timer // and creates all the other task. Then it deletes itself. // void StartupTask(void* pdata) { // Initialize BSP functions BSP_Init(); // re-init the UART so we can use the serial port initUART0(38400, UART_8N1, UART_FIFO_OFF, getFcclk()); // setup queues and semaphore needed for test threads MyQueue = OSQCreate(&Q1[0],Q1_SIZE); if (MyQueue == NULL) { DEBUGMSG(1,("StartupTask: failed to create queue.\n\r")); OSTaskDel(OS_PRIO_SELF); } MySem = OSSemCreate(1); if (MySem == NULL) { DEBUGMSG(1,("StartupTask: failed to create semaphore.\n\r")); OSTaskDel(OS_PRIO_SELF); } // create the the test tasks // we have OS_STK_GROWTH set to 1, so the stack grows from high to low OSTaskCreate(Task1, (void*)0, (void*)&Task1Stk[APP_TASK_DEFAULT_STK_SIZE-1], APP_TASK_TEST1_PRIO); OSTaskCreate(Task2, (void*)0, (void*)&Task2Stk[APP_TASK_DEFAULT_STK_SIZE-1], APP_TASK_TEST2_PRIO); OSTaskCreate(Task3, (void*)1000, (void*)&Task3Stk[APP_TASK_DEFAULT_STK_SIZE-1], APP_TASK_TEST3_PRIO); // delete ourselves, letting the work be done in the new tasks. OSTaskDel(OS_PRIO_SELF); } // Task 1,2 & 3 have dependencies on each otherthrough semaphores and queues. // They demonstrate tasking, delays and IPCs operating within the OS port // // Task1 prints an alternating message (Led On/Led Off) each time it wakes // up from the semaphore MySem. // void Task1(void* pdata) { INT8U err; BOOLEAN LedOn; LedOn = FALSE; DEBUGMSG(1,("Task1: begin\n\r")); for(;;) { OSSemPend(MySem, 0, &err); if (err != OS_NO_ERR) { DEBUGMSG(1,("Task1: failed to get semaphore, err: %d\n\r", err)); // now what should we do???????? } // toggle the LED and print a message if (LedOn==TRUE) { DEBUGMSG(1,("Task1: Led On\n\r")); LedOn = FALSE; } else { DEBUGMSG(1,("Task1: Led Off\n\r")); LedOn = TRUE; } SetLED(LedOn); } } // task 2 places a message into MyQueue every 500 msecs. void Task2(void* pdata) { long qmsg; INT32U count; INT8U err; count = 0; DEBUGMSG(1,("Task2: begin\n\r")); for(;;) { OSTimeDly(500); qmsg = count++; if (qmsg == (long)NULL) { // illegal to queue a NULL message qmsg = 1; } err = OSQPost(MyQueue,(void*)qmsg); if (err != OS_NO_ERR) { DEBUGMSG(1,("Task2: failed to post to queue, err: %d\n\r", err)); // now what should we do???????? } } } // task 3 waits on a message from MyQueue. When it reveives the message // it sets the semaphore MySem. // void Task3(void* pdata) { long qdata; volatile long passed_data; INT8U err; DEBUGMSG(1,("Task3: begin\n\r")); passed_data = (long)pdata; for(;;) { qdata = (long)OSQPend(MyQueue, 0, &err); if (err != OS_NO_ERR) { DEBUGMSG(1,("Task3: failed to pend from queue, err: %d\n\r", err)); // now what should we do???????? } if(qdata >= 100) /* use data somehow */ { if(passed_data++ == 2000) passed_data = passed_data; } err = OSSemPost(MySem); if (err != OS_NO_ERR) { DEBUGMSG(1,("Task3: failed to post to semaphore, err: %d\n\r", err)); // now what should we do???????? } } } // toggle the LED next to the display (labeled SD) static void SetLED(BOOLEAN On) { if (On) { WRITEREG32(FIO0CLR, SD_LED_BIT); } else { WRITEREG32(FIO0SET, SD_LED_BIT); } } bsp.c ===== .. code-block:: c static void Tmr_TickInit (void) { CPU_INT32U pclk_freq; CPU_INT32U rld_cnts; // VIC timer #0 Initialization WRITEREG32(VICINTSELECT, READREG32(VICINTSELECT) & ~(1 << VIC_TIMER0)); /* Configure the timer interrupt as an IRQ source */ WRITEREG32(VICVECTADDR4, (CPU_INT32U)Tmr_TickISR_Handler); /* Set the vector address */ WRITEREG32(VICINTENABLE, (1 << VIC_TIMER0)); /* Enable the timer interrupt source */ pclk_freq = BSP_CPU_PclkFreq(PCLKINDX_TIMER0); /* Get the peripheral clock frequency */ rld_cnts = pclk_freq / OS_TICKS_PER_SEC; /* Calculate the # of counts necessary for the OS ticker */ WRITEREG32(T0TCR, (1 << 1)); /* Disable and reset counter 0 and the prescale counter 0 */ WRITEREG32(T0TCR, 0); /* Clear the reset bit */ WRITEREG32(T0PC, 0); /* Prescaler is set to no division */ WRITEREG32(T0MR0, rld_cnts); WRITEREG32(T0MCR, 3); /* Interrupt on MR0 (reset TC), stop TC */ WRITEREG32(T0CCR, 0); /* Capture is disabled. */ WRITEREG32(T0EMR, 0); /* No external match output. */ WRITEREG32(T0TCR, 1); /* Enable timer 0 */ } /* ********************************************************************************************************* * Tmr_TickISR_Handler() * * Description : Handle the timer interrupt that is used to generate TICKs for uC/OS-II. * * Argument(s) : none. * * Return(s) : none. ********************************************************************************************************* */ void Tmr_TickISR_Handler (void) { WRITEREG32(T0IR, 0xFF); /* Clear timer #0 interrupt */ OSTimeTick(); /* Call uC/OS-II's OSTimeTick() */ } cpu_a.s ======= .. code-block:: c /*********************************************** >> Implement save of CPSR register ************************************************/ /* this is a two step process to avoid possibly having FIQ's masted during IRQs */ CPU_SR_Save: MRS r0, cpsr ORR r1, r0, #CPU_ARM_CTRL_INT_IRQDIS /* disable IRQs */ MSR cpsr_c, r1 ORR r1, r1, #CPU_ARM_CTRL_INT_FIQDIS /* disable FIQs */ MSR cpsr_c, r1 BX LR /* DISABLED, return the original CPSR contents in R0*/ /*********************************************** >> Implement restore of CPSR register ************************************************/ CPU_SR_Restore: /* See Note #2*/ MSR CPSR_c, R0 BX LR app_cfg.h ========= .. code-block:: c //default stack size for tasks in OS_STK units #define APP_TASK_DEFAULT_STK_SIZE 512 #define APP_TASK_START_STK_SIZE 512 //task priorities #define APP_TASK_START_PRIO 4 #define APP_TASK_TEST1_PRIO 5 #define APP_TASK_TEST2_PRIO 6 #define APP_TASK_TEST3_PRIO 7 #define OS_TASK_TMR_PRIO (OS_LOWEST_PRIO - 2) cpu.h ===== .. code-block:: c typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide */ typedef unsigned int OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */ os_cfg.h ======== .. code-block:: c #define OS_TICKS_PER_SEC 1000 /* Set the number of ticks in one second */